home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Nebula 1
/
Nebula One.iso
/
Misc
/
msql-1.0.6
/
src
/
msql
/
msql_yacc.y
< prev
next >
Wrap
Text File
|
1995-05-28
|
6KB
|
463 lines
/*
** msql_yacc.y -
**
**
** Copyright (c) 1993 David J. Hughes
**
** Permission to use, copy, and distribute for non-commercial purposes,
** is hereby granted without fee, providing that the above copyright
** notice appear in all copies and that both the copyright notice and this
** permission notice appear in supporting documentation.
**
** The software may be modified for your own purposes, but modified versions
** may not be distributed.
**
** This software is provided "as is" without any expressed or implied warranty.
**
** ID = "$Id:"
**
*/
%{
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <netdb.h>
#include "msql_priv.h"
#include "msql.h"
int yylineno;
extern int selectWildcard,
selectDistinct,
yytoklen;
ident_t *msqlCreateIdent();
#define myFree(x) Free(x,__FILE__,__LINE__)
%}
%token END_OF_INPUT
%token GE
%token LE
%token NE
%token EQ
%token GT
%token LT
%token CREATE
%token DROP
%token INSERT
%token DELETE
%token SELECT
%token UPDATE
%token ALL
%token DISTINCT
%token WHERE
%token ORDER
%token FROM
%token INTO
%token TABLE
%token BY
%token ASC
%token DESC
%token LIKE
%token AND
%token OR
%token VALUES
%token SET
%token NOT
%token NULLSYM
%token PRIMARY
%token KEY
%token IDENT
%token TEXT
%token NUM
%token REAL_NUM
%token INT
%token BOOL
%token CHAR
%token REAL
%%
/*
** High level definitions
**
** Note : The lex input routines return a flag character of \001 to
** indicate the end of input. This allows me to force a query
** to be terminated at a know point (ie. the end of the query-buf)
** Without this something like "select * from foo ;" is found by
** yacc to be a legit query followed by a second query containing
** only a ';' character. The flag is generated by msqlInput() and
** msqlFlexInput() in msql_io.c
*/
query
: /* NULL */
| verb_clause END_OF_INPUT
{
msqlProcessQuery();
msqlClean();
}
verb_clause
: create
| select
| drop
| insert
| update
| delete
/*
** Create : create database tables
*/
create
: CREATE TABLE IDENT '('
{
command = CREATE;
msqlAddTable($3,NULL);
}
field_list ')'
field_list
: field_list_item
| field_list ',' field_list_item
field_list_item
: qual_ident type opt_nullspec opt_keyspec
{
if(msqlAddField($1,$2,arrayLen,notnullflag,keyflag)<0)
{
msqlClean();
return;
}
if (arrayLen)
{
(void)myFree(arrayLen);
}
arrayLen = 0;
}
type
: INT
| REAL
| CHAR '(' NUM ')'
{
arrayLen = $3;
$$=$1;
}
opt_nullspec
: /* NULL */
{
notnullflag = 0;
}
| NOT NULLSYM
{
notnullflag = 1;
}
opt_keyspec
: /* NULL */
{
keyflag = 0;
}
| PRIMARY KEY
{
keyflag = 1;
}
/*
** Select : retrieve data from table
*/
select
: SELECT dist_qual item_list FROM table_list where_clause order_clause
{
command = SELECT;
}
dist_qual
: /* NULL */
{ selectDistinct = 0; }
| ALL
{ selectDistinct = 0; }
| DISTINCT
{ selectDistinct = 1; }
item_list
: item_list ',' field
| field
| '*'
{
ident_t *tmp;
tmp = msqlCreateIdent(NULL,"*");
msqlAddField(tmp,0,0,0,0);
selectWildcard = 1;
}
field
: qual_ident
{
msqlAddField($1,0,0,0,0);
}
table_list
: IDENT
{
msqlAddTable($1,NULL);
}
| IDENT EQ IDENT
{
msqlAddTable($1, $3);
}
| table_list ',' IDENT
{
msqlAddTable($3,NULL);
}
| table_list ',' IDENT EQ IDENT
{
msqlAddTable($3, $5);
}
where_clause
: /* NULL */
| WHERE cond_list
cond_list
: cond_list cond_cont qual_ident cond_op cond_literal
{ msqlAddCond($3,$4,$5,$2); }
| qual_ident cond_op cond_literal
{ msqlAddCond($1,$2,$3,NO_BOOL); }
cond_cont
: AND
{ $$ = (char *)AND_BOOL; }
| OR
{ $$ = (char *)OR_BOOL; }
cond_op
: EQ
{ $$ = (char *)EQ_OP; }
| NE
{ $$ = (char *)NE_OP; }
| LT
{ $$ = (char *)LT_OP; }
| LE
{ $$ = (char *)LE_OP; }
| GT
{ $$ = (char *)GT_OP; }
| GE
{ $$ = (char *)GE_OP; }
| LIKE
{ $$ = (char *)LIKE_OP; }
| NOT LIKE
{ $$ = (char *)NOT_LIKE_OP; }
order_clause
:
| ORDER BY order_list
order_list
: order_list ',' qual_ident order_dir
{ msqlAddOrder($3,(int) $4); }
| qual_ident order_dir
{ msqlAddOrder($1,(int) $2); }
order_dir
: ASC
| DESC
| /* NULL */
{ $$ = (char *) ASC; }
/*
** Drop : delete entire table
*/
drop
: DROP TABLE IDENT
{
command = DROP;
msqlAddTable($3,NULL);
}
/*
** Insert : add new data to table
*/
insert
: INSERT INTO IDENT opt_field_spec
{
command = INSERT;
msqlAddTable($3,NULL);
if ($4)
expandTableFields($3);
}
VALUES '(' values ')'
opt_field_spec
: /* NULL */
{
ident_t *tmp;
tmp = msqlCreateIdent(NULL,"*");
msqlAddField(tmp,0,0,0,0);
$$ = (char *) 1;
}
| '(' fields ')'
{
$$ = (char *) 0;
}
fields
: fields ',' qual_ident
{
msqlAddField($3,0,0,0,0);
}
| qual_ident
{
msqlAddField($1,0,0,0,0);
}
values
: values ',' literal
{
msqlAddFieldValue($3);
}
| literal
{
msqlAddFieldValue($1);
}
/*
** Update : replace a table entry
*/
update
: UPDATE IDENT SET update_list where_clause
{
command = UPDATE;
msqlAddTable($2,NULL);
}
update_list
: update_list ',' qual_ident EQ literal
{ msqlAddField($3,0,0,0,0);
msqlAddFieldValue($5); }
| qual_ident EQ literal
{ msqlAddField($1,0,0,0,0);
msqlAddFieldValue($3); }
/*
** Delete : conditionally delete table entries (or all entries)
*/
delete
: DELETE FROM IDENT where_clause
{
command = DELETE;
msqlAddTable($3,NULL);
}
/*
** Common definitions
*/
literal
: TEXT
{
$$ = (char *)msqlCreateValue($1,CHAR_TYPE,yytoklen);
(void)myFree($1);
}
| NUM
{
$$ = (char *)msqlCreateValue($1,INT_TYPE,0);
(void)myFree($1);
}
| REAL_NUM
{
$$ = (char *)msqlCreateValue($1,REAL_TYPE,0);
(void)myFree($1);
}
| NULLSYM
{
$$ = (char *)msqlCreateValue("null",NULL_TYPE,0);
}
cond_literal
: literal
{
$$ = $1;
}
| qual_ident
{
$$ = (char *)msqlCreateValue($1,IDENT_TYPE);
}
qual_ident
: IDENT
{
$$ = (char *)msqlCreateIdent(NULL,$1);
(void)myFree($1);
if ($$ == NULL)
{
msqlClean();
return;
}
}
| IDENT '.' IDENT
{
$$ = (char *)msqlCreateIdent($1,$3);
(void)myFree($1);
(void)myFree($3);
if ($$ == NULL)
{
msqlClean();
return;
}
}